home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / dev / src / expat-src.lha / expat-1.95.2 / xmlwf / xmlwf.c < prev   
Encoding:
C/C++ Source or Header  |  2001-10-25  |  17.6 KB  |  792 lines

  1. /*
  2. Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
  3. See the file COPYING for copying permission.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10.  
  11. #ifndef AMIGA
  12. #include "expat.h"
  13. #else
  14. #include <exec/types.h>
  15. #include <exec/memory.h>
  16. #include <expat/expat.h>
  17. #include <proto/exec.h>
  18. #include <proto/expat.h>
  19. struct Library *ExpatBase = NULL;
  20. #endif
  21.  
  22. #include "codepage.h"
  23. #include "xmlfile.h"
  24. #include "xmltchar.h"
  25.  
  26. #ifdef _MSC_VER
  27. #include <crtdbg.h>
  28. #endif
  29.  
  30.  
  31. /* This ensures proper sorting. */
  32.  
  33. #define NSSEP T('\001')
  34.  
  35. static void characterData(void *userData, const XML_Char *s, int len)
  36. {
  37.   FILE *fp = userData;
  38.   for (; len > 0; --len, ++s) {
  39.     switch (*s) {
  40.     case T('&'):
  41.       fputts(T("&"), fp);
  42.       break;
  43.     case T('<'):
  44.       fputts(T("<"), fp);
  45.       break;
  46.     case T('>'):
  47.       fputts(T(">"), fp);
  48.       break;
  49. #ifdef W3C14N
  50.     case 13:
  51.       fputts(T(" "), fp);
  52.       break;
  53. #else
  54.     case T('"'):
  55.       fputts(T("""), fp);
  56.       break;
  57.     case 9:
  58.     case 10:
  59.     case 13:
  60.       ftprintf(fp, T("&#%d;"), *s);
  61.       break;
  62. #endif
  63.     default:
  64.       puttc(*s, fp);
  65.       break;
  66.     }
  67.   }
  68. }
  69.  
  70. static void attributeValue(FILE *fp, const XML_Char *s)
  71. {
  72.   puttc(T('='), fp);
  73.   puttc(T('"'), fp);
  74.   for (;;) {
  75.     switch (*s) {
  76.     case 0:
  77.     case NSSEP:
  78.       puttc(T('"'), fp);
  79.       return;
  80.     case T('&'):
  81.       fputts(T("&"), fp);
  82.       break;
  83.     case T('<'):
  84.       fputts(T("<"), fp);
  85.       break;
  86.     case T('"'):
  87.       fputts(T("""), fp);
  88.       break;
  89. #ifdef W3C14N
  90.     case 9:
  91.       fputts(T(" "), fp);
  92.       break;
  93.     case 10:
  94.       fputts(T(" "), fp);
  95.       break;
  96.     case 13:
  97.       fputts(T(" "), fp);
  98.       break;
  99. #else
  100.     case T('>'):
  101.       fputts(T(">"), fp);
  102.       break;
  103.     case 9:
  104.     case 10:
  105.     case 13:
  106.       ftprintf(fp, T("&#%d;"), *s);
  107.       break;
  108. #endif
  109.     default:
  110.       puttc(*s, fp);
  111.       break;
  112.     }
  113.     s++;
  114.   }
  115. }
  116.  
  117. /* Lexicographically comparing UTF-8 encoded attribute values,
  118. is equivalent to lexicographically comparing based on the character number. */
  119.  
  120. static int attcmp(const void *att1, const void *att2)
  121. {
  122.   return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2);
  123. }
  124.  
  125. static void startElement(void *userData, const XML_Char *name, const XML_Char **atts)
  126. {
  127.   int nAtts;
  128.   const XML_Char **p;
  129.   FILE *fp = userData;
  130.   puttc(T('<'), fp);
  131.   fputts(name, fp);
  132.  
  133.   p = atts;
  134.   while (*p)
  135.     ++p;
  136.   nAtts = (p - atts) >> 1;
  137.   if (nAtts > 1)
  138.     qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp);
  139.   while (*atts) {
  140.     puttc(T(' '), fp);
  141.     fputts(*atts++, fp);
  142.     attributeValue(fp, *atts);
  143.     atts++;
  144.   }
  145.   puttc(T('>'), fp);
  146. }
  147.  
  148. static void endElement(void *userData, const XML_Char *name)
  149. {
  150.   FILE *fp = userData;
  151.   puttc(T('<'), fp);
  152.   puttc(T('/'), fp);
  153.   fputts(name, fp);
  154.   puttc(T('>'), fp);
  155. }
  156.  
  157. static int nsattcmp(const void *p1, const void *p2)
  158. {
  159.   const XML_Char *att1 = *(const XML_Char **)p1;
  160.   const XML_Char *att2 = *(const XML_Char **)p2;
  161.   int sep1 = (tcsrchr(att1, NSSEP) != 0);
  162.   int sep2 = (tcsrchr(att1, NSSEP) != 0);
  163.   if (sep1 != sep2)
  164.     return sep1 - sep2;
  165.   return tcscmp(att1, att2);
  166. }
  167.  
  168. static void startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
  169. {
  170.   int nAtts;
  171.   int nsi;
  172.   const XML_Char **p;
  173.   FILE *fp = userData;
  174.   const XML_Char *sep;
  175.   puttc(T('<'), fp);
  176.  
  177.   sep = tcsrchr(name, NSSEP);
  178.   if (sep) {
  179.     fputts(T("n1:"), fp);
  180.     fputts(sep + 1, fp);
  181.     fputts(T(" xmlns:n1"), fp);
  182.     attributeValue(fp, name);
  183.     nsi = 2;
  184.   }
  185.   else {
  186.     fputts(name, fp);
  187.     nsi = 1;
  188.   }
  189.  
  190.   p = atts;
  191.   while (*p)
  192.     ++p;
  193.   nAtts = (p - atts) >> 1;
  194.   if (nAtts > 1)
  195.     qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp);
  196.   while (*atts) {
  197.     name = *atts++;
  198.     sep = tcsrchr(name, NSSEP);
  199.     puttc(T(' '), fp);
  200.     if (sep) {
  201.       ftprintf(fp, T("n%d:"), nsi);
  202.       fputts(sep + 1, fp);
  203.     }
  204.     else
  205.       fputts(name, fp);
  206.     attributeValue(fp, *atts);
  207.     if (sep) {
  208.       ftprintf(fp, T(" xmlns:n%d"), nsi++);
  209.       attributeValue(fp, name);
  210.     }
  211.     atts++;
  212.   }
  213.   puttc(T('>'), fp);
  214. }
  215.  
  216. static void endElementNS(void *userData, const XML_Char *name)
  217. {
  218.   FILE *fp = userData;
  219.   const XML_Char *sep;
  220.   puttc(T('<'), fp);
  221.   puttc(T('/'), fp);
  222.   sep = tcsrchr(name, NSSEP);
  223.   if (sep) {
  224.     fputts(T("n1:"), fp);
  225.     fputts(sep + 1, fp);
  226.   }
  227.   else
  228.     fputts(name, fp);
  229.   puttc(T('>'), fp);
  230. }
  231.  
  232. #ifndef W3C14N
  233.  
  234. static void processingInstruction(void *userData, const XML_Char *target, const XML_Char *data)
  235. {
  236.   FILE *fp = userData;
  237.   puttc(T('<'), fp);
  238.   puttc(T('?'), fp);
  239.   fputts(target, fp);
  240.   puttc(T(' '), fp);
  241.   fputts(data, fp);
  242.   puttc(T('?'), fp);
  243.   puttc(T('>'), fp);
  244. }
  245.  
  246. #endif /* not W3C14N */
  247.  
  248. static void defaultCharacterData(XML_Parser parser, const XML_Char *s, int len)
  249. {
  250.   XML_DefaultCurrent(parser);
  251. }
  252.  
  253. static void defaultStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts)
  254. {
  255.   XML_DefaultCurrent(parser);
  256. }
  257.  
  258. static void defaultEndElement(XML_Parser parser, const XML_Char *name)
  259. {
  260.   XML_DefaultCurrent(parser);
  261. }
  262.  
  263. static void defaultProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data)
  264. {
  265.   XML_DefaultCurrent(parser);
  266. }
  267.  
  268. static void nopCharacterData(XML_Parser parser, const XML_Char *s, int len)
  269. {
  270. }
  271.  
  272. static void nopStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts)
  273. {
  274. }
  275.  
  276. static void nopEndElement(XML_Parser parser, const XML_Char *name)
  277. {
  278. }
  279.  
  280. static void nopProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data)
  281. {
  282. }
  283.  
  284. static void markup(XML_Parser parser, const XML_Char *s, int len)
  285. {
  286.   FILE *fp = XML_GetUserData(parser);
  287.   for (; len > 0; --len, ++s)
  288.     puttc(*s, fp);
  289. }
  290.  
  291. static
  292. void metaLocation(XML_Parser parser)
  293. {
  294.   const XML_Char *uri = XML_GetBase(parser);
  295.   if (uri)
  296.     ftprintf(XML_GetUserData(parser), T(" uri=\"%s\""), uri);
  297.   ftprintf(XML_GetUserData(parser),
  298.            T(" byte=\"%ld\" nbytes=\"%d\" line=\"%d\" col=\"%d\""),
  299.        XML_GetCurrentByteIndex(parser),
  300.        XML_GetCurrentByteCount(parser),
  301.        XML_GetCurrentLineNumber(parser),
  302.        XML_GetCurrentColumnNumber(parser));
  303. }
  304.  
  305. static
  306. void metaStartDocument(XML_Parser parser)
  307. {
  308.   fputts(T("<document>\n"), XML_GetUserData(parser));
  309. }
  310.  
  311. static
  312. void metaEndDocument(XML_Parser parser)
  313. {
  314.   fputts(T("</document>\n"), XML_GetUserData(parser));
  315. }
  316.  
  317. static
  318. void metaStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts)
  319. {
  320.   FILE *fp = XML_GetUserData(parser);
  321.   const XML_Char **specifiedAttsEnd
  322.     = atts + XML_GetSpecifiedAttributeCount(parser);
  323.   const XML_Char **idAttPtr;
  324.   int idAttIndex = XML_GetIdAttributeIndex(parser);
  325.   if (idAttIndex < 0)
  326.     idAttPtr = 0;
  327.   else
  328.     idAttPtr = atts + idAttIndex;
  329.     
  330.   ftprintf(fp, T("<starttag name=\"%s\""), name);
  331.   metaLocation(parser);
  332.   if (*atts) {
  333.     fputts(T(">\n"), fp);
  334.     do {
  335.       ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
  336.       characterData(fp, atts[1], tcslen(atts[1]));
  337.       if (atts >= specifiedAttsEnd)
  338.     fputts(T("\" defaulted=\"yes\"/>\n"), fp);
  339.       else if (atts == idAttPtr)
  340.     fputts(T("\" id=\"yes\"/>\n"), fp);
  341.       else
  342.     fputts(T("\"/>\n"), fp);
  343.     } while (*(atts += 2));
  344.     fputts(T("</starttag>\n"), fp);
  345.   }
  346.   else
  347.     fputts(T("/>\n"), fp);
  348. }
  349.  
  350. static
  351. void metaEndElement(XML_Parser parser, const XML_Char *name)
  352. {
  353.   FILE *fp = XML_GetUserData(parser);
  354.   ftprintf(fp, T("<endtag name=\"%s\""), name);
  355.   metaLocation(parser);
  356.   fputts(T("/>\n"), fp);
  357. }
  358.  
  359. static
  360. void metaProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data)
  361. {
  362.   FILE *fp = XML_GetUserData(parser);
  363.   ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
  364.   characterData(fp, data, tcslen(data));
  365.   puttc(T('"'), fp);
  366.   metaLocation(parser);
  367.   fputts(T("/>\n"), fp);
  368. }
  369.  
  370. static
  371. void metaComment(XML_Parser parser, const XML_Char *data)
  372. {
  373.   FILE *fp = XML_GetUserData(parser);
  374.   fputts(T("<comment data=\""), fp);
  375.   characterData(fp, data, tcslen(data));
  376.   puttc(T('"'), fp);
  377.   metaLocation(parser);
  378.   fputts(T("/>\n"), fp);
  379. }
  380.  
  381. static
  382. void metaStartCdataSection(XML_Parser parser)
  383. {
  384.   FILE *fp = XML_GetUserData(parser);
  385.   fputts(T("<startcdata"), fp);
  386.   metaLocation(parser);
  387.   fputts(T("/>\n"), fp);
  388. }
  389.  
  390. static
  391. void metaEndCdataSection(XML_Parser parser)
  392. {
  393.   FILE *fp = XML_GetUserData(parser);
  394.   fputts(T("<endcdata"), fp);
  395.   metaLocation(parser);
  396.   fputts(T("/>\n"), fp);
  397. }
  398.  
  399. static
  400. void metaCharacterData(XML_Parser parser, const XML_Char *s, int len)
  401. {
  402.   FILE *fp = XML_GetUserData(parser);
  403.   fputts(T("<chars str=\""), fp);
  404.   characterData(fp, s, len);
  405.   puttc(T('"'), fp);
  406.   metaLocation(parser);
  407.   fputts(T("/>\n"), fp);
  408. }
  409.  
  410. static
  411. void metaStartDoctypeDecl(XML_Parser parser,
  412.               const XML_Char *doctypeName,
  413.               const XML_Char *sysid,
  414.               const XML_Char *pubid,
  415.               int has_internal_subset)
  416. {
  417.   FILE *fp = XML_GetUserData(parser);
  418.   ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
  419.   metaLocation(parser);
  420.   fputts(T("/>\n"), fp);
  421. }
  422.  
  423. static
  424. void metaEndDoctypeDecl(XML_Parser parser)
  425. {
  426.   FILE *fp = XML_GetUserData(parser);
  427.   fputts(T("<enddoctype"), fp);
  428.   metaLocation(parser);
  429.   fputts(T("/>\n"), fp);
  430. }
  431.  
  432. static
  433. void metaNotationDecl(XML_Parser parser,
  434.               const XML_Char *notationName,
  435.               const XML_Char *base,
  436.               const XML_Char *systemId,
  437.               const XML_Char *publicId)
  438. {
  439.   FILE *fp = XML_GetUserData(parser);
  440.   ftprintf(fp, T("<notation name=\"%s\""), notationName);
  441.   if (publicId)
  442.     ftprintf(fp, T(" public=\"%s\""), publicId);
  443.   if (systemId) {
  444.     fputts(T(" system=\""), fp);
  445.     characterData(fp, systemId, tcslen(systemId));
  446.     puttc(T('"'), fp);
  447.   }
  448.   metaLocation(parser);
  449.   fputts(T("/>\n"), fp);
  450. }
  451.  
  452.  
  453. static
  454. void metaEntityDecl(XML_Parser parser,
  455.             const XML_Char *entityName,
  456.             int  is_param,
  457.             const XML_Char *value,
  458.             int  value_length,
  459.             const XML_Char *base,
  460.             const XML_Char *systemId,
  461.             const XML_Char *publicId,
  462.             const XML_Char *notationName)
  463. {
  464.   FILE *fp = XML_GetUserData(parser);
  465.  
  466.   if (value) {
  467.     ftprintf(fp, T("<entity name=\"%s\""), entityName);
  468.     metaLocation(parser);
  469.     puttc(T('>'), fp);
  470.     characterData(fp, value, value_length);
  471.     fputts(T("</entity/>\n"), fp);
  472.   }
  473.   else if (notationName) {
  474.     ftprintf(fp, T("<entity name=\"%s\""), entityName);
  475.     if (publicId)
  476.       ftprintf(fp, T(" public=\"%s\""), publicId);
  477.     fputts(T(" system=\""), fp);
  478.     characterData(fp, systemId, tcslen(systemId));
  479.     puttc(T('"'), fp);
  480.     ftprintf(fp, T(" notation=\"%s\""), notationName);
  481.     metaLocation(parser);
  482.     fputts(T("/>\n"), fp);
  483.   }
  484.   else {
  485.     ftprintf(fp, T("<entity name=\"%s\""), entityName);
  486.     if (publicId)
  487.       ftprintf(fp, T(" public=\"%s\""), publicId);
  488.     fputts(T(" system=\""), fp);
  489.     characterData(fp, systemId, tcslen(systemId));
  490.     puttc(T('"'), fp);
  491.     metaLocation(parser);
  492.     fputts(T("/>\n"), fp);
  493.   }
  494. }
  495.  
  496. static
  497. void metaStartNamespaceDecl(XML_Parser parser,
  498.                 const XML_Char *prefix,
  499.                 const XML_Char *uri)
  500. {
  501.   FILE *fp = XML_GetUserData(parser);
  502.   fputts(T("<startns"), fp);
  503.   if (prefix)
  504.     ftprintf(fp, T(" prefix=\"%s\""), prefix);
  505.   if (uri) {
  506.     fputts(T(" ns=\""), fp);
  507.     characterData(fp, uri, tcslen(uri));
  508.     fputts(T("\"/>\n"), fp);
  509.   }
  510.   else
  511.     fputts(T("/>\n"), fp);
  512. }
  513.  
  514. static
  515. void metaEndNamespaceDecl(XML_Parser parser, const XML_Char *prefix)
  516. {
  517.   FILE *fp = XML_GetUserData(parser);
  518.   if (!prefix)
  519.     fputts(T("<endns/>\n"), fp);
  520.   else
  521.     ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
  522. }
  523.  
  524. static
  525. int unknownEncodingConvert(void *data, const char *p)
  526. {
  527.   return codepageConvert(*(int *)data, p);
  528. }
  529.  
  530. static
  531. int unknownEncoding(void *userData,
  532.             const XML_Char *name,
  533.             XML_Encoding *info)
  534. {
  535.   int cp;
  536.   static const XML_Char prefixL[] = T("windows-");
  537.   static const XML_Char prefixU[] = T("WINDOWS-");
  538.   int i;
  539.  
  540.   for (i = 0; prefixU[i]; i++)
  541.     if (name[i] != prefixU[i] && name[i] != prefixL[i])
  542.       return 0;
  543.   
  544.   cp = 0;
  545.   for (; name[i]; i++) {
  546.     static const XML_Char digits[] = T("0123456789");
  547.     const XML_Char *s = tcschr(digits, name[i]);
  548.     if (!s)
  549.       return 0;
  550.     cp *= 10;
  551.     cp += s - digits;
  552.     if (cp >= 0x10000)
  553.       return 0;
  554.   }
  555.   if (!codepageMap(cp, info->map))
  556.     return 0;
  557.   info->convert = unknownEncodingConvert;
  558.   /* We could just cast the code page integer to a void *,
  559.   and avoid the use of release. */
  560.   info->release = free;
  561.   info->data = malloc(sizeof(int));
  562.   if (!info->data)
  563.     return 0;
  564.   *(int *)info->data = cp;
  565.   return 1;
  566. }
  567.  
  568. static
  569. int notStandalone(void *userData)
  570. {
  571.   return 0;
  572. }
  573.  
  574. static
  575. void usage(const XML_Char *prog)
  576. {
  577.   ftprintf(stderr, T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog);
  578.   exit(1);
  579. }
  580.  
  581. int tmain(int argc, XML_Char **argv)
  582. {
  583.   int i, j;
  584.   const XML_Char *outputDir = 0;
  585.   const XML_Char *encoding = 0;
  586.   unsigned processFlags = XML_MAP_FILE;
  587.   int windowsCodePages = 0;
  588.   int outputType = 0;
  589.   int useNamespaces = 0;
  590.   int requireStandalone = 0;
  591.   int paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  592.  
  593. #ifdef _MSC_VER
  594.   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
  595. #endif
  596.  
  597.   i = 1;
  598.   j = 0;
  599.   while (i < argc) {
  600.     if (j == 0) {
  601.       if (argv[i][0] != T('-'))
  602.     break;
  603.       if (argv[i][1] == T('-') && argv[i][2] == T('\0')) {
  604.     i++;
  605.     break;
  606.       }
  607.       j++;
  608.     }
  609.     switch (argv[i][j]) {
  610.     case T('r'):
  611.       processFlags &= ~XML_MAP_FILE;
  612.       j++;
  613.       break;
  614.     case T('s'):
  615.       requireStandalone = 1;
  616.       j++;
  617.       break;
  618.     case T('n'):
  619.       useNamespaces = 1;
  620.       j++;
  621.       break;
  622.     case T('p'):
  623.       paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS;
  624.       /* fall through */
  625.     case T('x'):
  626.       processFlags |= XML_EXTERNAL_ENTITIES;
  627.       j++;
  628.       break;
  629.     case T('w'):
  630.       windowsCodePages = 1;
  631.       j++;
  632.       break;
  633.     case T('m'):
  634.       outputType = 'm';
  635.       j++;
  636.       break;
  637.     case T('c'):
  638.       outputType = 'c';
  639.       useNamespaces = 0;
  640.       j++;
  641.       break;
  642.     case T('t'):
  643.       outputType = 't';
  644.       j++;
  645.       break;
  646.     case T('d'):
  647.       if (argv[i][j + 1] == T('\0')) {
  648.     if (++i == argc)
  649.       usage(argv[0]);
  650.     outputDir = argv[i];
  651.       }
  652.       else
  653.     outputDir = argv[i] + j + 1;
  654.       i++;
  655.       j = 0;
  656.       break;
  657.     case T('e'):
  658.       if (argv[i][j + 1] == T('\0')) {
  659.     if (++i == argc)
  660.       usage(argv[0]);
  661.     encoding = argv[i];
  662.       }
  663.       else
  664.     encoding = argv[i] + j + 1;
  665.       i++;
  666.       j = 0;
  667.       break;
  668.     case T('\0'):
  669.       if (j > 1) {
  670.     i++;
  671.     j = 0;
  672.     break;
  673.       }
  674.       /* fall through */
  675.     default:
  676.       usage(argv[0]);
  677.     }
  678.   }
  679.  
  680.   
  681. #ifdef AMIGA
  682.   ExpatBase = (APTR) OpenLibrary("expat.library", 0);
  683.   if(!ExpatBase)
  684.   {
  685.     printf("\nCouldn't open expat.library\n");
  686.     exit(20);
  687.   }
  688. #endif
  689.   
  690.   if (i == argc)
  691.     usage(argv[0]);
  692.   for (; i < argc; i++) {
  693.     FILE *fp = 0;
  694.     XML_Char *outName = 0;
  695.     int result;
  696.     XML_Parser parser;
  697.     if (useNamespaces)
  698.       parser = XML_ParserCreateNS(encoding, NSSEP);
  699.     else
  700.       parser = XML_ParserCreate(encoding);
  701.     if (requireStandalone)
  702.       XML_SetNotStandaloneHandler(parser, notStandalone);
  703.     XML_SetParamEntityParsing(parser, paramEntityParsing);
  704.     if (outputType == 't') {
  705.       /* This is for doing timings; this gives a more realistic estimate of
  706.      the parsing time. */
  707.       outputDir = 0;
  708.       XML_SetElementHandler(parser, nopStartElement, nopEndElement);
  709.       XML_SetCharacterDataHandler(parser, nopCharacterData);
  710.       XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction);
  711.     }
  712.     else if (outputDir) {
  713.       const XML_Char *file = argv[i];
  714.       if (tcsrchr(file, T('/')))
  715.     file = tcsrchr(file, T('/')) + 1;
  716. #ifdef WIN32
  717.       if (tcsrchr(file, T('\\')))
  718.     file = tcsrchr(file, T('\\')) + 1;
  719. #endif
  720.       outName = malloc((tcslen(outputDir) + tcslen(file) + 2) * sizeof(XML_Char));
  721.       tcscpy(outName, outputDir);
  722.       tcscat(outName, T("/"));
  723.       tcscat(outName, file);
  724.       fp = tfopen(outName, T("wb"));
  725.       if (!fp) {
  726.     tperror(outName);
  727. #ifdef AMIGA  
  728.     CloseLibrary((APTR) ExpatBase);
  729. #endif
  730.     exit(1);
  731.       }
  732.       setvbuf(fp, NULL, _IOFBF, 16384);
  733. #ifdef XML_UNICODE
  734.       puttc(0xFEFF, fp);
  735. #endif
  736.       XML_SetUserData(parser, fp);
  737.       switch (outputType) {
  738.       case 'm':
  739.     XML_UseParserAsHandlerArg(parser);
  740.     XML_SetElementHandler(parser, metaStartElement, metaEndElement);
  741.     XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction);
  742.     XML_SetCommentHandler(parser, metaComment);
  743.     XML_SetCdataSectionHandler(parser, metaStartCdataSection, metaEndCdataSection);
  744.     XML_SetCharacterDataHandler(parser, metaCharacterData);
  745.     XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl, metaEndDoctypeDecl);
  746.     XML_SetEntityDeclHandler(parser, metaEntityDecl);
  747.     XML_SetNotationDeclHandler(parser, metaNotationDecl);
  748.     XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl, metaEndNamespaceDecl);
  749.     metaStartDocument(parser);
  750.     break;
  751.       case 'c':
  752.     XML_UseParserAsHandlerArg(parser);
  753.     XML_SetDefaultHandler(parser, markup);
  754.     XML_SetElementHandler(parser, defaultStartElement, defaultEndElement);
  755.     XML_SetCharacterDataHandler(parser, defaultCharacterData);
  756.     XML_SetProcessingInstructionHandler(parser, defaultProcessingInstruction);
  757.     break;
  758.       default:
  759.     if (useNamespaces)
  760.       XML_SetElementHandler(parser, startElementNS, endElementNS);
  761.     else
  762.       XML_SetElementHandler(parser, startElement, endElement);
  763.     XML_SetCharacterDataHandler(parser, characterData);
  764. #ifndef W3C14N
  765.     XML_SetProcessingInstructionHandler(parser, processingInstruction);
  766. #endif /* not W3C14N */
  767.     break;
  768.       }
  769.     }
  770.     if (windowsCodePages)
  771.       XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0);
  772.     result = XML_ProcessFile(parser, argv[i], processFlags);
  773.     if (outputDir) {
  774.       if (outputType == 'm')
  775.     metaEndDocument(parser);
  776.       fclose(fp);
  777.       if (!result)
  778.     tremove(outName);
  779.       free(outName);
  780.     }
  781.     XML_ParserFree(parser);
  782.   }
  783.   
  784. #ifdef AMIGA  
  785.   CloseLibrary((APTR) ExpatBase);
  786.   exit(0);
  787. #else
  788.   return 0;
  789. #endif
  790.   
  791. }
  792.